var octree = null;
var cameraSpeed = 0;
var strafeSpeed = 0;
var maxCameraSpeed = 1;
var yawRate = 0;
var pitchRate = 0;
var maxPitchRate = 0.016;
var cameraPosition = new Vector(0, 0, 0);
var cameraDirection = new Vector(0, 0, 1);
var upDirection = new Vector(0, 1, 0);
var keys = new Array(); // Stored keyboard state

// The multiplayer features have been disabled until they are done.
//var players = new Array();
//setInterval("getPlayerData()", 1000);

function getPlayerData() {
    // Send own player data and get data from other players
    $.getJSON('/update-position-dummy.php', function(data) {
        players = []
        for (i=0; i < data.length; i++) {
            player = new Player(data[i].id, data[i].x, data[i].y, data[i].z, 1)
            players.push(player)
        }
    });
}

function initOctree() {
    octree = new Octree(0, 0, 0, 100000, 10);
    var n = stars.length;
    for (var i = 0; i < n; ++i) {
	var star = stars[i];
	star = new Star(star[0], star[1], star[2], star[3], star[4]);
	octree.insert(star);
    }
}

function initKeys() {
    for (var i = 0; i < 256; ++i) {
	keys[i] = 0;
    }
}

function onKeyUp() {
    keys[event.keyCode] = 0;
}

function onKeyDown() {
    keys[event.keyCode] = 1;
}

function render() {
    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");
    context.fillStyle = "rgb(0, 0, 0)";
    context.fillRect(0, 0, canvas.width, canvas.height);
    var leftDirection = Vector.crossProduct(cameraDirection, upDirection);
    octree.render(cameraPosition, cameraDirection, upDirection, leftDirection,
		  canvas.width, canvas.height, context, 0.000005);
}

function drawLine(context, x1, y1, x2, y2, radius) {
    context.beginPath();
    context.moveTo(x1, y1);
    context.lineTo(x2, y2);
    context.closePath();
    context.stroke();
    context.beginPath();
    context.arc(x2, y2, radius, 0 , 2 * Math.PI, false);
    context.fill();
}

function drawCompass() {
    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");
    var leftDirection = Vector.crossProduct(cameraDirection, upDirection);
    var handLength = 35;
    var centerX = canvas.width - 50;
    var centerY = canvas.height - 50;
    radius = 4;
    context.strokeStyle = "rgb(64, 255, 64)";
    context.fillStyle = "rgb(64, 255, 64)";
    dx = handLength * cameraDirection.x;
    dy = handLength * cameraDirection.y;
    drawLine(context, centerX, centerY, centerX + dx, centerY + dy, radius);
    context.fillStyle = "rgb(64, 64, 255)";
    drawLine(context, centerX, centerY, centerX - dx, centerY - dy, radius);
    context.fillStyle = "rgb(64, 255, 64)";
    dx = handLength * leftDirection.x;
    dy = handLength * leftDirection.y;
    drawLine(context, centerX, centerY, centerX + dx, centerY + dy, radius);
    drawLine(context, centerX, centerY, centerX - dx, centerY - dy, radius);
    dx = handLength * upDirection.x;
    dy = handLength * upDirection.y;
    drawLine(context, centerX, centerY, centerX + dx, centerY + dy, radius);
    context.fillStyle = "rgb(255, 64, 64)";
    drawLine(context, centerX, centerY, centerX - dx, centerY - dy, radius);
}

function renderPlayers() {
    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");
    //context.fillStyle = "rgb(0, 0, 0)";
    //context.fillRect(0, 0, canvas.width, canvas.height);
    var rh = -cameraBearing;
    var rv = cameraInclination;
    var crh = Math.cos(rh);
    var crv = Math.cos(rv);
    var srh = Math.sin(rh);
    var srv = Math.sin(rv);

    var i = 0;
    for (i=0; i < players.length; i++) {
        players[i].render(cameraX, cameraY, cameraZ,
            crh, srh, crv, srv,
            canvas.width, canvas.height, context);
    }
}

function updateCamera() {
    if (keys[87]) {
	cameraSpeed += 0.1;
    }
    if (keys[83]) {
	cameraSpeed -= 0.1;
    }
    if (keys[65]) {
	strafeSpeed -= 0.1;
    }
    if (keys[68]) {
	strafeSpeed += 0.1;
    }
    cameraSpeed *= 0.9;
    cameraSpeed = Math.min(cameraSpeed, maxCameraSpeed);
    cameraSpeed = Math.max(cameraSpeed, -maxCameraSpeed);
    strafeSpeed *= 0.9;
    strafeSpeed = Math.min(strafeSpeed, maxCameraSpeed);
    strafeSpeed = Math.max(strafeSpeed, -maxCameraSpeed);
    var left = Vector.crossProduct(cameraDirection, upDirection);
    cameraPosition.addInPlace(left.multiplyScalar(strafeSpeed));
    cameraPosition.addInPlace(cameraDirection.multiplyScalar(cameraSpeed));
    if (keys[38]) {
	pitchRate += 0.005;
    }
    if (keys[40]) {
	pitchRate -= 0.005;
    }
    if (keys[37]) {
	yawRate += 0.005;
    }
    if (keys[39]) {
	yawRate -= 0.005;
    }
    pitchRate = Math.min(pitchRate, maxPitchRate);
    pitchRate = Math.max(pitchRate, -maxPitchRate);
    cameraDirection = cameraDirection.rotate(left, pitchRate);
    upDirection = upDirection.rotate(left, pitchRate);
    pitchRate *= 0.9;

    yawRate = Math.min(yawRate, maxPitchRate);
    yawRate = Math.max(yawRate, -maxPitchRate);
    cameraDirection = cameraDirection.rotate(upDirection, yawRate);
    yawRate *= 0.9;
}

function resizeCanvas() {
    var canvas = document.getElementById("canvas");
    var w = window.innerWidth - 10;
    var h = window.innerHeight - 10;
    if (canvas.width != w) {
	canvas.width = w;
    }
    if (canvas.height != h) {
	canvas.height = h;
    }
}

function doOneFrame() {
    resizeCanvas();
    updateCamera();
    render();
    // The multiplayer features have been disabled until they are finished.
    //renderPlayers()
    drawCompass();
    setTimeout("doOneFrame()", 0);
}

function init() {
    initKeys();
    initOctree();
    doOneFrame();
    //setInterval("doOneFrame()", 100);
}
